package com.sinosoft.msf.base.supplier.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.sinosoft.msf.base.supplier.dao.base.*;
import com.sinosoft.msf.base.supplier.expection.BizException;
import com.sinosoft.msf.base.supplier.pojo.*;
import com.sinosoft.msf.base.supplier.pojo.entity.*;
import com.sinosoft.msf.base.supplier.props.IpAddressEnum;
import com.sinosoft.msf.base.supplier.props.NoticeTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author huangzhihao
 **/
@Service
@Slf4j
public class CompanyNoticeService {
    @Autowired
    SNoticeRecordMapper sNoticeRecordMapper;
    @Autowired
    SIpRecordMapper sIpRecordMapper;
    @Autowired
    SNoticeCopmanyMapper sNoticeCopmanyMapper;
    @Autowired
    SCompanyMapper sCompanyMapper;
    @Autowired
    SCompanyInfoMapper sCompanyInfoMapper;

    public List<SNoticeRecord> markWarnList(CompanyQueryReqPojo companyQueryReqPojo) {
        CompanyQueryReqPojo.ParamData paramData = companyQueryReqPojo.getParamData();
//        PageHelper.startPage(companyQueryReqPojo.getPageNo(), companyQueryReqPojo.getPageSize());
//        Page<SNoticeRecord> companyMarkWarnList = (Page<SNoticeRecord>) sCompanyMapper.selectCompanyMarkWarnList(paramData);
        List<SNoticeRecord> noticeRecordList = sCompanyMapper.selectNoticeRecordList(paramData);
        return noticeRecordList;
    }

    public void markNoticeRead(JSONObject jsonObject, OptVo optVo) {
        String id = jsonObject.getString("id");
        String type = jsonObject.getString("type");
//        SNoticeRecord noticeRecord = sNoticeRecordMapper.selectByPrimaryKey(id);
        if (sNoticeRecordMapper.selectByPrimaryKey(id) == null) {
            throw new BizException("消息不存在");
        }
        SNoticeRecord noticeRecord = new SNoticeRecord();
        noticeRecord.setId(id);
        noticeRecord.setUpdateId(optVo.getUserId());
        noticeRecord.setUpdateDate(DateUtil.date());
        if ("A".equals(type)) {
            noticeRecord.setNoticeStatus("1");
        } else if ("B".equals(type)) {
            noticeRecord.setReadDetail("1");
        }
        sNoticeRecordMapper.updateByPrimaryKeySelective(noticeRecord);
    }

    private void historyIpNoticeGenerate() {
        log.info("相同ip地址消息生成开始");
        //查找所有ip记录插入到新表中
        List<SProjectCompany> companyList = sCompanyMapper.selectPriceIp();
        for (SProjectCompany projectCompany : companyList) {
            saveIpAddressSync(projectCompany.getPriceIp(), IpAddressEnum.C.name(), projectCompany.getCompanyId());
        }
        log.info("相同ip地址消息生成完成");
        sameHistoryHandle(NoticeTypeEnum.C.name());
    }

    private void historyPersonNoticeGenerate() {
        log.info("相同人员消息生成开始");
        //查出全部供应商
        List<SCompanyInfo> companyInfoPojoList = sCompanyMapper.selectCompanyPojoList();
        for (SCompanyInfo pojo : companyInfoPojoList) {
            CompanyInfoPojo supplier = new CompanyInfoPojo();
            supplier.setComId(pojo.getId());
            supplier.setBenefiter(pojo.getBenefiter());
            supplier.setLegalPerson(pojo.getLegalPerson());
            supplier.setContracts(sCompanyMapper.queryContractList(pojo.getId(), pojo.getModId()));
            sameConcatCheckSync(supplier);
        }
        log.info("相同人员消息生成完成");
        sameHistoryHandle(NoticeTypeEnum.B.name());
    }

    private void sameHistoryHandle(String noticeType) {
        log.info("历史相同消息处理开始");
        List<Map<String, Object>> mapList = sCompanyMapper.selectSameHistory(noticeType);
        if (CollectionUtil.isNotEmpty(mapList)) {
            for (Map<String, Object> map : mapList) {
                int num = Integer.parseInt(String.valueOf(map.get("num"))) - 1;
                sCompanyMapper.updateSameHistory(String.valueOf(map.get("extra")), num);
            }
        }
        log.info("历史相同消息处理完成");
    }

    public void markNoticeGenerate(JSONObject jsonObject) {
        String flag = jsonObject.getString("flag");
        if (!StringUtils.isEmpty(flag)) {
            if ("1".equals(flag)) {
                historyIpNoticeGenerate();
                return;
            }
            if ("2".equals(flag)) {
                historyPersonNoticeGenerate();
                return;
            }
        }
        String date = jsonObject.getString("date");
        if (StringUtils.isEmpty(date)) {
            date = DateUtil.formatDate(new Date());
        }
        log.info("执行日期为{}", date);
        String markPrefix = "距离停用截止时间还有";
        String markSuffix = "天，请确认启用该供应商还是再次延长停用时间!";
        // 查找全部停用周期
        List<SNoticeRecord> stopNoticeRecord = sCompanyMapper.selectStopNoticeRecord(date);
        if (!CollectionUtil.isEmpty(stopNoticeRecord)) {
            List<SNoticeCompany> noticeCompanyList = new ArrayList<>();
            List<SNoticeRecord> noticeRecordList = new ArrayList<>();
            for (SNoticeRecord noticeRecord : stopNoticeRecord) {
                // 逻辑删除已存在的供应商消息
                sCompanyMapper.updateNoticeRecord(noticeRecord.getCompanyId(), NoticeTypeEnum.A.name());
                // 插入消息主表
                SNoticeRecord notice = new SNoticeRecord();
                notice.setId(IdUtil.simpleUUID());
                notice.setNoticeType(NoticeTypeEnum.A.name());
                notice.setNoticeStatus("0");
                notice.setCompanyId(noticeRecord.getCompanyId());
                notice.setCompanyName(noticeRecord.getCompanyName());
                notice.setReadDetail("0");
                notice.setDeleted("n");
                notice.setCreatedId("admin");
                notice.setCreatedDate(DateUtil.date());
                notice.setExtra(noticeRecord.getCompanyName() + markPrefix + noticeRecord.getExtra() + markSuffix);
                noticeRecordList.add(notice);
                //插入消息和供应商关联表
                SNoticeCompany noticeCompany = new SNoticeCompany();
                noticeCompany.setId(IdUtil.simpleUUID());
                noticeCompany.setNoticeId(notice.getId());
                noticeCompany.setCompanyId(notice.getCompanyId());
                noticeCompany.setDeleted("n");
                noticeCompany.setCreatedDate(DateUtil.date());
                noticeCompanyList.add(noticeCompany);
            }
            sNoticeRecordMapper.insertList(noticeRecordList);
            sNoticeCopmanyMapper.insertList(noticeCompanyList);
        }
    }

    public List<NoticeIpDetailResp> noticeIpDetail(JSONObject jsonObject) {
        String id = jsonObject.getString("id");
        List<NoticeIpDetailResp> noticeIpDetailResp = sCompanyMapper.selectNoticeIpCompany(id);
        String ipAddress = noticeIpDetailResp.stream().map(NoticeIpDetailResp::getIpAddress).collect(Collectors.toList()).get(0);
        String ipPrefix = getIpPrefix(ipAddress);
        for (NoticeIpDetailResp resp : noticeIpDetailResp) {
            NoticeIpDetailResp ipDetail = sCompanyMapper.selectIpDetail(ipPrefix, resp.getCompanyId());
            if (!IpAddressEnum.C.name().equals(ipDetail.getIpGetStep())) {
                ipDetail.setUploadPriceId(null);
                ipDetail.setUploadPriceName(null);
            }
            BeanUtil.copyProperties(ipDetail, resp, CopyOptions.create().setIgnoreNullValue(true));
            resp.setProjectList(sCompanyMapper.selectNoticeProjectList(resp.getCompanyId()));
        }
        return noticeIpDetailResp;
    }

    /**
     * 获取IP前缀
     *
     * @param ipAddress ip地址
     * @return ip地址前三位
     */
    private String getIpPrefix(String ipAddress) {
        if (StringUtils.isEmpty(ipAddress)) {
            return "";
        }
        int lastIndex = ipAddress.lastIndexOf(".");
        String ipPrefix = "";
        // 截取前三段IP地址
        if (lastIndex >= 2) { // 确保存在至少三段且格式正确
            ipPrefix = ipAddress.substring(0, lastIndex);
        }
        log.info("获取到的IP前缀为:{}", ipPrefix);
        return ipPrefix;
    }

    public List<NoticePersonDetailResp> noticePersonDetail(JSONObject jsonObject) {
        String id = jsonObject.getString("id");
        List<NoticePersonDetailResp> noticePersonDetailResp = sCompanyMapper.selectNoticePersonCompany(id);
        for (NoticePersonDetailResp resp : noticePersonDetailResp) {
            resp.setProjectList(sCompanyMapper.selectNoticeProjectList(resp.getCompanyId()));
        }
        return noticePersonDetailResp;
    }

    public void sameConcatCheckSync(CompanyInfoPojo supplier) {
        sameConcatCheck(supplier);
    }

    @Async
    public void sameConcatCheck(CompanyInfoPojo supplier) {
        log.info("供应商相同人员信息校验开始");
        List<String> sameCompanyList = new ArrayList<>();
        for (Contract contract : supplier.getContracts()) {
            NoticePersonDetailResp query = new NoticePersonDetailResp();
            query.setLegalPerson(supplier.getLegalPerson());
            query.setBenefiter(supplier.getBenefiter());
            query.setContactEmail(contract.getContactEmail());
            query.setContactName(contract.getContactName());
            query.setContactPhone(contract.getContactPhone());
            sameCompanyList = sCompanyMapper.selectSameCompanyPerson(query);
            if (sameCompanyList.size() > 1) {
                log.info("存在相同人员信息的供应商为:{}", JSONObject.toJSONString(sameCompanyList));
                generateNotice(NoticeTypeEnum.B.name(), sameCompanyList, null);
                break;
            }
        }
    }

    public void saveIpAddressSync(String clientIP, String type, String id) {
        saveIpAddress(clientIP, type, id);
    }

    @Async
    public void saveIpAddress(String clientIP, String type, String id) {
        log.info("获取到的客户端IP:{}类型为:{}", clientIP, type);
        SIpRecord sIpRecord = new SIpRecord();
        sIpRecord.setId(IdUtil.simpleUUID());
        sIpRecord.setBussId(id);
        sIpRecord.setBussType(type);
        sIpRecord.setIpAddress(clientIP);
        sIpRecord.setDeleted("n");
        sIpRecord.setCreatedDate(DateUtil.date());
        sIpRecordMapper.insert(sIpRecord);
        //查询供应商id是否有相同ip地址且供应商标记存在为空
        List<String> sameCompanyList = sCompanyMapper.selectSameCompanyByIp(clientIP);
        if (sameCompanyList.size() > 1) {
            log.info("{}存在相同ip地址的供应商为:{}", clientIP, JSONObject.toJSONString(sameCompanyList));
            generateNotice(NoticeTypeEnum.C.name(), sameCompanyList, clientIP);
        }
    }

    private void generateNotice(String noticeType, List<String> sameCompanyList, String bussId) {
        List<SNoticeCompany> noticeCompanyList = new ArrayList<>();
        //插入消息提醒表
        SNoticeRecord notice = new SNoticeRecord();
        notice.setNoticeType(noticeType);
        notice.setCompanyId(bussId);
        notice.setExtra(getNoticeContent(sameCompanyList, noticeType));
        notice.setId(IdUtil.simpleUUID());
        notice.setNoticeStatus("0");
        notice.setReadDetail("0");
        notice.setDeleted("n");
        notice.setCreatedId("admin");
        notice.setCreatedDate(DateUtil.date());
        sNoticeRecordMapper.insert(notice);
        for (String companyId : sameCompanyList) {
            //插入消息和供应商关联表
            SNoticeCompany noticeCompany = new SNoticeCompany();
            noticeCompany.setId(IdUtil.simpleUUID());
            noticeCompany.setNoticeId(notice.getId());
            noticeCompany.setCompanyId(companyId);
            noticeCompany.setDeleted("n");
            noticeCompany.setCreatedDate(DateUtil.date());
            noticeCompanyList.add(noticeCompany);
        }
        sNoticeCopmanyMapper.insertList(noticeCompanyList);
    }

    private String getNoticeContent(List<String> ids, String type) {
        String ipSuffix = "存在相同IP地址，请及时甄别!";
        String concatSuffix = "存在相同人员信息，请及时甄别!";
        StringBuilder sb = new StringBuilder();
        //查询供应商姓名，只取前三个
        String prefix = sCompanyMapper.selectCompanyName(ids);
        sb.append(prefix);
        if (ids.size() > 3) {
            sb.append("等");
        }
        if (type.equals(NoticeTypeEnum.B.name())) {
            sb.append(concatSuffix);
        } else if (type.equals(NoticeTypeEnum.C.name())) {
            sb.append(ipSuffix);
        }
        return String.valueOf(sb);
    }
}